<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
	<title>Mixing exact search with stemming | ElasticSearch 7.7 权威指南中文版</title>
	<meta name="keywords" content="ElasticSearch 权威指南中文版, elasticsearch 7, es7, 实时数据分析，实时数据检索" />
    <meta name="description" content="ElasticSearch 权威指南中文版, elasticsearch 7, es7, 实时数据分析，实时数据检索" />
    <!-- Give IE8 a fighting chance -->
    <!--[if lt IE 9]>
    <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
    <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
    <![endif]-->
	<link rel="stylesheet" type="text/css" href="../static/styles.css" />
	<script>
	var _link = 'mixing-exact-search-with-stemming.html';
    </script>
</head>
<body>
<div class="main-container">
    <section id="content">
        <div class="content-wrapper">
            <section id="guide" lang="zh_cn">
                <div class="container">
                    <div class="row">
                        <div class="col-xs-12 col-sm-8 col-md-8 guide-section">
                            <div style="color:gray; word-break: break-all; font-size:12px;">原英文版地址: <a href="https://www.elastic.co/guide/en/elasticsearch/reference/7.7/mixing-exact-search-with-stemming.html" rel="nofollow" target="_blank">https://www.elastic.co/guide/en/elasticsearch/reference/7.7/mixing-exact-search-with-stemming.html</a>, 原文档版权归 www.elastic.co 所有<br/>本地英文版地址: <a href="../en/mixing-exact-search-with-stemming.html" rel="nofollow" target="_blank">../en/mixing-exact-search-with-stemming.html</a></div>
                        <!-- start body -->
                  <div class="page_header">
<strong>重要</strong>: 此版本不会发布额外的bug修复或文档更新。最新信息请参考 <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/index.html" rel="nofollow">当前版本文档</a>。
</div>
<div id="content">
<div class="breadcrumbs">
<span class="breadcrumb-link"><a href="index.html">Elasticsearch Guide [7.7]</a></span>
»
<span class="breadcrumb-link"><a href="how-to.html">How To</a></span>
»
<span class="breadcrumb-link"><a href="recipes.html">Recipes</a></span>
»
<span class="breadcrumb-node">Mixing exact search with stemming</span>
</div>
<div class="navheader">
<span class="prev">
<a href="recipes.html">« Recipes</a>
</span>
<span class="next">
<a href="consistent-scoring.html">Getting consistent scoring »</a>
</span>
</div>
<div class="section">
<div class="titlepage"><div><div>
<h2 class="title">
<a id="mixing-exact-search-with-stemming"></a>Mixing exact search with stemming<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch/edit/7.7/docs/reference/how-to/recipes/stemming.asciidoc">edit</a>
</h2>
</div></div></div>
<p>When building a search application, stemming is often a must as it is desirable
for a query on <code class="literal">skiing</code> to match documents that contain <code class="literal">ski</code> or <code class="literal">skis</code>. But
what if a user wants to search for <code class="literal">skiing</code> specifically? The typical way to do
this would be to use a <a class="xref" href="multi-fields.html" title="fields">multi-field</a> in order to have the same
content indexed in two different ways:</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">PUT index
{
  "settings": {
    "analysis": {
      "analyzer": {
        "english_exact": {
          "tokenizer": "standard",
          "filter": [
            "lowercase"
          ]
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "body": {
        "type": "text",
        "analyzer": "english",
        "fields": {
          "exact": {
            "type": "text",
            "analyzer": "english_exact"
          }
        }
      }
    }
  }
}

PUT index/_doc/1
{
  "body": "Ski resort"
}

PUT index/_doc/2
{
  "body": "A pair of skis"
}

POST index/_refresh</pre>
</div>
<div class="console_widget" data-snippet="snippets/1301.console"></div>
<p>With such a setup, searching for <code class="literal">ski</code> on <code class="literal">body</code> would return both documents:</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">GET index/_search
{
  "query": {
    "simple_query_string": {
      "fields": [ "body" ],
      "query": "ski"
    }
  }
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/1302.console"></div>
<div class="pre_wrapper lang-console-result">
<pre class="programlisting prettyprint lang-console-result">{
  "took": 2,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped" : 0,
    "failed": 0
  },
  "hits": {
    "total" : {
        "value": 2,
        "relation": "eq"
    },
    "max_score": 0.18232156,
    "hits": [
      {
        "_index": "index",
        "_type": "_doc",
        "_id": "1",
        "_score": 0.18232156,
        "_source": {
          "body": "Ski resort"
        }
      },
      {
        "_index": "index",
        "_type": "_doc",
        "_id": "2",
        "_score": 0.18232156,
        "_source": {
          "body": "A pair of skis"
        }
      }
    ]
  }
}</pre>
</div>
<p>On the other hand, searching for <code class="literal">ski</code> on <code class="literal">body.exact</code> would only return
document <code class="literal">1</code> since the analysis chain of <code class="literal">body.exact</code> does not perform
stemming.</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">GET index/_search
{
  "query": {
    "simple_query_string": {
      "fields": [ "body.exact" ],
      "query": "ski"
    }
  }
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/1303.console"></div>
<div class="pre_wrapper lang-console-result">
<pre class="programlisting prettyprint lang-console-result">{
  "took": 1,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped" : 0,
    "failed": 0
  },
  "hits": {
    "total" : {
        "value": 1,
        "relation": "eq"
    },
    "max_score": 0.8025915,
    "hits": [
      {
        "_index": "index",
        "_type": "_doc",
        "_id": "1",
        "_score": 0.8025915,
        "_source": {
          "body": "Ski resort"
        }
      }
    ]
  }
}</pre>
</div>
<p>This is not something that is easy to expose to end users, as we would need to
have a way to figure out whether they are looking for an exact match or not and
redirect to the appropriate field accordingly. Also what to do if only parts of
the query need to be matched exactly while other parts should still take
stemming into account?</p>
<p>Fortunately, the <code class="literal">query_string</code> and <code class="literal">simple_query_string</code> queries have a feature
that solves this exact problem: <code class="literal">quote_field_suffix</code>. This tells Elasticsearch
that the words that appear in between quotes are to be redirected to a different
field, see below:</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">GET index/_search
{
  "query": {
    "simple_query_string": {
      "fields": [ "body" ],
      "quote_field_suffix": ".exact",
      "query": "\"ski\""
    }
  }
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/1304.console"></div>
<div class="pre_wrapper lang-console-result">
<pre class="programlisting prettyprint lang-console-result">{
  "took": 2,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped" : 0,
    "failed": 0
  },
  "hits": {
    "total" : {
        "value": 1,
        "relation": "eq"
    },
    "max_score": 0.8025915,
    "hits": [
      {
        "_index": "index",
        "_type": "_doc",
        "_id": "1",
        "_score": 0.8025915,
        "_source": {
          "body": "Ski resort"
        }
      }
    ]
  }
}</pre>
</div>
<p>In the above case, since <code class="literal">ski</code> was in-between quotes, it was searched on the
<code class="literal">body.exact</code> field due to the <code class="literal">quote_field_suffix</code> parameter, so only document
<code class="literal">1</code> matched. This allows users to mix exact search with stemmed search as they
like.</p>
<div class="note admon">
<div class="icon"></div>
<div class="admon_content">
<p>If the choice of field passed in <code class="literal">quote_field_suffix</code> does not exist
the search will fall back to using the default field for the query string.</p>
</div>
</div>
</div>
<div class="navfooter">
<span class="prev">
<a href="recipes.html">« Recipes</a>
</span>
<span class="next">
<a href="consistent-scoring.html">Getting consistent scoring »</a>
</span>
</div>
</div>

                  <!-- end body -->
                        </div>
                        <div class="col-xs-12 col-sm-4 col-md-4" id="right_col">
                        
                        </div>
                    </div>
                </div>
            </section>
        </div>
    </section>
</div>
<script src="../static/cn.js"></script>
</body>
</html>